from typing import Optional, List
from tempfile import gettempdir
from pathlib import Path
from importlib.metadata import version 

from pydantic_settings import BaseSettings, SettingsConfigDict
from yarl import URL


TEMP_DIR = Path(gettempdir())

APP_DIR = Path(__file__).parent

class Settings(BaseSettings):
    
    # app settings
    app_name: str = "awesome_fastapi_demo"
    app_version: str = version(app_name)
    app_description: str = 'awesome fastapi demo'

    # unicorn settings
    host: str = '127.0.0.1'
    port: int = 3000
    workers_count: int = 1
    enable_reload: bool = False
    
    # Current environment
    environment: str = "dev"
    
    # log settings
    log_dir: Path = Path("logs") / app_name
    log_level: str = "DEBUG"
    log_rotation: str = "00:00"
    log_retention: str = "3 days"
    log_compression: str = "zip"
    
    # Redis settings
    redis_host: str = f"{app_name}-redis"
    redis_port: int = 6379
    redis_user: Optional[str] = None
    redis_pass: Optional[str] = None
    redis_base: Optional[int] = None
    
    # Variables for RabbitMQ
    rabbit_host: str = f"{app_name}-rmq"
    rabbit_port: int = 5672
    rabbit_user: str = "guest"
    rabbit_pass: str = "guest"
    rabbit_vhost: str = "/"

    rabbit_pool_size: int = 2
    rabbit_channel_pool_size: int = 10
    
    # This variable is used to define
    # multiproc_dir. It's required for [uvi|guni]corn projects.
    prometheus_dir: Path = TEMP_DIR / "prom"
    
    # db settings
    db_file: Path = TEMP_DIR / 'db.sqlite3'
    
    kafka_bootstrap_servers: List[str] = [f"{app_name}-kafka:9092"]

    prometheus_dir: Path = TEMP_DIR / "prom"
    @property
    def db_url(self) -> URL:
        return URL.build(scheme="sqlite", path=f"///{self.db_file}")
    
    
    @property
    def redis_url(self) -> URL:
        """
        Assemble REDIS URL from settings.

        :return: redis URL.
        """
        path = ""
        if self.redis_base is not None:
            path = f"/{self.redis_base}"
        return URL.build(
            scheme="redis",
            host=self.redis_host,
            port=self.redis_port,
            user=self.redis_user,
            password=self.redis_pass,
            path=path,
        )
        
    @property
    def rabbit_url(self) -> URL:
        """
        Assemble RabbitMQ URL from settings.

        :return: rabbit URL.
        """
        return URL.build(
            scheme="amqp",
            host=self.rabbit_host,
            port=self.rabbit_port,
            user=self.rabbit_user,
            password=self.rabbit_pass,
            path=self.rabbit_vhost,
        )
            
    model_config = SettingsConfigDict(
        env_file=".env",
        env_prefix=f"{app_name.upper()}_",
        env_file_encoding="utf-8",
    )
    

settings = Settings()